package com.school.edupoint.websocket;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.school.edupoint.vo.MessageVO;
import org.springframework.web.socket.CloseStatus;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;
import org.springframework.web.socket.handler.TextWebSocketHandler;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

public class MyTextWebSocketHandler extends TextWebSocketHandler {
    // 保存所有在线用户的session
    private static final ConcurrentHashMap<String, WebSocketSession> userSessionMap = new ConcurrentHashMap<>();
    // 按用户类型分组：PC端管理员、学生端
    private static final CopyOnWriteArraySet<WebSocketSession> pcSessions = new CopyOnWriteArraySet<>();
    private static final CopyOnWriteArraySet<WebSocketSession> studentSessions = new CopyOnWriteArraySet<>();
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception {
        String payload = message.getPayload();
        System.out.println("收到WebSocket消息: " + payload);
        MessageVO msg = objectMapper.readValue(payload, MessageVO.class);

        // 认证消息
        if ("PC_Auth".equals(msg.getMessageType())) {
            userSessionMap.put(msg.getUserId(), session);
            pcSessions.add(session);
            System.out.println("PC端认证成功，userId: " + msg.getUserId() + ", 当前PC端连接数: " + pcSessions.size());
            // 发送JSON格式的认证成功响应
            MessageVO authSuccess = new MessageVO();
            authSuccess.setUserId(msg.getUserId());
            authSuccess.setMessageType("AUTH_SUCCESS");
            authSuccess.setTitle("认证成功");
            authSuccess.setContent("管理员认证成功，userId=" + msg.getUserId());
            authSuccess.setParam("");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(authSuccess)));
            return;
        } else if ("Student_Auth".equals(msg.getMessageType())) {
            userSessionMap.put(msg.getUserId(), session);
            studentSessions.add(session);
            System.out.println("学生端认证成功，userId: " + msg.getUserId() + ", 当前学生端连接数: " + studentSessions.size());
            // 发送JSON格式的认证成功响应
            MessageVO authSuccess = new MessageVO();
            authSuccess.setUserId(msg.getUserId());
            authSuccess.setMessageType("AUTH_SUCCESS");
            authSuccess.setTitle("认证成功");
            authSuccess.setContent("学生认证成功，userId=" + msg.getUserId());
            authSuccess.setParam("");
            session.sendMessage(new TextMessage(objectMapper.writeValueAsString(authSuccess)));
            return;
        }

        // 根据消息类型进行不同的处理
        switch (msg.getMessageType()) {
            case "GIFT_EXCHANGE":
                System.out.println("收到学生礼物兑换消息，准备向管理员广播: " + payload);
                broadcastToAllAdmins(msg);
                break;
            case "CHECKIN_SUCCESS":
                System.out.println("收到学生打卡成功消息，准备向管理员广播: " + payload);
                broadcastToAllAdmins(msg);
                break;
            case "GIFT_SHIPPED":
                System.out.println("收到礼物发货消息，准备向学生发送: " + payload);
                // 发送给特定学生
                if (msg.getUserId() != null) {
                    sendToUser(msg.getUserId(), msg);
                    System.out.println("已向学生发送礼物发货通知：学生ID " + msg.getUserId());
                }
                break;
            case "GIFT_DELIVERED":
                System.out.println("收到礼物送达消息，准备向学生发送: " + payload);
                // 发送给特定学生
                if (msg.getUserId() != null) {
                    sendToUser(msg.getUserId(), msg);
                    System.out.println("已向学生发送礼物送达通知：学生ID " + msg.getUserId());
                }
                break;
            case "GIFT_CANCELLED":
                System.out.println("收到礼物取消消息，准备向学生发送: " + payload);
                // 发送给特定学生
                if (msg.getUserId() != null) {
                    sendToUser(msg.getUserId(), msg);
                    System.out.println("已向学生发送礼物取消通知：学生ID " + msg.getUserId());
                }
                break;
            default:
                // 其它类型消息可做回显或忽略
                System.out.println("收到未处理的业务消息类型: " + msg.getMessageType());
                break;
        }
    }

    @Override
    public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        // 从所有集合中移除session
        userSessionMap.entrySet().removeIf(entry -> entry.getValue().equals(session));
        pcSessions.remove(session);
        studentSessions.remove(session);
    }

    // 按userId推送消息
    public static void sendToUser(String userId, MessageVO messageVO) {
        WebSocketSession session = userSessionMap.get(userId);
        if (session != null && session.isOpen()) {
            try {
                String json = objectMapper.writeValueAsString(messageVO);
                session.sendMessage(new TextMessage(json));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    // 广播给所有学生
    public static void broadcastToAllStudents(MessageVO messageVO) {
        System.out.println("开始向学生端广播消息，当前学生端连接数: " + studentSessions.size());
        if (studentSessions.isEmpty()) {
            System.out.println("警告：当前没有学生端连接，无法发送通知");
            return;
        }
        
        studentSessions.forEach(session -> {
            if (session.isOpen()) {
                try {
                    String json = objectMapper.writeValueAsString(messageVO);
                    session.sendMessage(new TextMessage(json));
                    System.out.println("成功向学生端发送消息: " + json);
                } catch (Exception e) {
                    System.err.println("向学生端发送消息失败: " + e.getMessage());
                    e.printStackTrace();
                }
            } else {
                System.out.println("学生端session已关闭，跳过发送");
            }
        });
    }

    // 广播给所有PC端管理员
    public static void broadcastToAllAdmins(MessageVO messageVO) {
        System.out.println("开始向PC端广播消息，当前PC端连接数: " + pcSessions.size());
        pcSessions.forEach(session -> {
            if (session.isOpen()) {
                try {
                    String json = objectMapper.writeValueAsString(messageVO);
                    session.sendMessage(new TextMessage(json));
                    System.out.println("成功向PC端发送消息: " + json);
                } catch (Exception e) {
                    System.err.println("向PC端发送消息失败: " + e.getMessage());
                    e.printStackTrace();
                }
            } else {
                System.out.println("PC端session已关闭，跳过发送");
            }
        });
    }

    // 广播给所有在线用户
    public static void broadcastToAll(MessageVO messageVO) {
        userSessionMap.forEach((userId, session) -> {
            if (session.isOpen()) {
                try {
                    String json = objectMapper.writeValueAsString(messageVO);
                    session.sendMessage(new TextMessage(json));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
} 